package com.codi.api.controller.organ;

import com.codi.api.controller.BaseController;
import com.codi.api.security.UserUtil;
import com.codi.api.validation.AccountValidation;
import com.codi.base.exception.BaseAppException;
import com.codi.base.log.annotation.Loggable;
import com.codi.base.util.EqualsUtil;
import com.codi.base.web.RequestUtils;
import com.codi.bus.constant.GlobalConstant;
import com.codi.bus.core.dao.OrganAgentDao;
import com.codi.bus.core.domain.OrganAgent;
import com.codi.bus.core.domain.OrganProfile;
import com.codi.bus.core.domain.User;
import com.codi.bus.core.resultModel.AccountOpenResult;
import com.codi.bus.core.resultModel.BaseResult;
import com.codi.bus.core.resultModel.LoginResult;
import com.codi.bus.core.resultModel.ValidateTokenResult;
import com.codi.bus.core.service.SMSSimpleService;
import com.codi.bus.core.service.UserService;
import com.codi.bus.core.service.model.UserModel;
import com.codi.bus.core.service.organ.OrganAccountService;
import com.codi.bus.core.service.organ.OrganProfileService;
import com.codi.bus.core.vo.OrganProfileVo;
import com.codi.bus.core.vo.OrganProfileVoNew;
import com.codi.bus.core.vo.OrganRegisterVo;
import com.codi.bus.core.vo.UserBankVo;
import com.codi.bus.exception.BaseException;
import com.codi.message.constant.ErrorConst;
import com.codi.message.util.MessageUtil;
import com.codi.superman.base.domain.SysBanner;
import com.codi.superman.base.service.SysBannerService;
import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.List;

/**
 * 机构账户
 *
 * @author shi.pengyan
 * @version 1.0 2017-08-31 14:53
 * @since 1.0
 */
@Slf4j
@RestController
@RequestMapping("/organ/acct")
public class OrganAccountController extends BaseController {

    @Resource
    private OrganAccountService organAccountService;
    @Autowired
    private AccountValidation accountValidation;

    @Autowired
    private UserService userService;

    @Autowired
    private SMSSimpleService smsSimpleService;

    @Autowired
    private HttpServletRequest request;

    @Autowired
    private OrganProfileService organProfileService;

    @Autowired
    private SysBannerService sysBannerService;
    @Resource
    private OrganAgentDao organAgentDao;


    /**
     * 机构注册
     *
     * @param registerVo
     * @return
     * @throws BaseException
     */
    @PostMapping("/register")
    @Loggable
    public BaseResult register(@Validated OrganRegisterVo registerVo) throws BaseException {
        User entity = new User();

        BeanUtils.copyProperties(registerVo, entity);

        // 验证输入
        LoginResult result = accountValidation.validateOrganRegister(entity);
        if (result != null) {
            return result;
        }

        // 获取IP地址
        String ip = RequestUtils.getIpAddr(request);

        // 完成手机号注册
        User user = userService.registerOrganAccount(entity);
        OrganAgent agent = organAgentDao.getEntityByMobile(entity.getUserMobile());
        result = new LoginResult();
        result.setSuccess(true);
        UserModel model = new UserModel();
        if (agent != null) {
            model.setIsContact(true);
        } else {
            model.setIsContact(false);
        }
        model.setUserId(user.getUserId());
        model.setIsOrg(true);

        result.setUser(model);
        result.setToken(userService.generateToken(user.getUserId(), registerVo.getDeviceId(), registerVo.getChannelId(), ip));


        //发送短信
        smsSimpleService.sendAsync(user.getUserMobile(), GlobalConstant.SMS_TPL_NOTIFY_ORGANIZATION,
            GlobalConstant.SMS_TPL_NOTIFY_ORGANIZATION_LOGIN_ID, "" + user.getUserId());
        log.debug("send suc sms");

        return result;
    }

    /**
     * 一次性添加所有资料
     *
     * @param organProfileVo
     * @param userBankVo
     * @return
     * @throws BaseAppException
     */
    @PostMapping("add_profile")
    @Loggable
    public BaseResult addProfile(@Validated OrganProfileVo organProfileVo,
                                 @Validated UserBankVo userBankVo) throws BaseAppException {

        BaseResult result = accountValidation.validateOrgProfile(organProfileVo,
            UserUtil.getLoginUserId(), GlobalConstant.ACTION_ADD);

        if (!result.getSuccess()) {
            return result;
        }

        return userService.addOrganProfile(UserUtil.getLoginUserId(), organProfileVo, userBankVo);
    }


    /**
     * 一次性添加所有资料（新）
     */
    @PostMapping("add_profile_new")
    @Loggable
    public BaseResult addProfileNew(@Validated OrganProfileVoNew organProfileVoNew, @Validated UserBankVo userBankVo) throws BaseAppException {
        String token = request.getHeader(GlobalConstant.HEADER_AUTH_TOKEN);
        String deviceId = request.getHeader(GlobalConstant.HEADER_APP_DEVICE);
        ValidateTokenResult validateTokenResult = userService.validateToken(token, deviceId);
        Long userId = validateTokenResult.getUserId();
        BaseResult result = accountValidation.validateOrgProfileNew(organProfileVoNew, userId, GlobalConstant.ACTION_ADD);
        if (!result.getSuccess()) {
            return result;
        }
        return organAccountService.addOrganProfile(userId, organProfileVoNew, userBankVo);
    }

    /**
     * 修改机构 开户文件上传方式
     */
    @PostMapping("add_organ_profile_channel")
    @Loggable
    public BaseResult addOrganProfileChannel(String channel, Long profileId) {
        BaseResult result = new BaseResult();
        OrganProfile profile = organProfileService.getById(profileId);
        if (profile == null) {
            return result;
        }
        if ("email".equals(channel.trim())) {
            profile.setState(GlobalConstant.ORGAN_STATE_AUDITING);
        }
        profile.setChannel(channel);
        organProfileService.addOrUpdateByProfileId(profile);
        return result;
    }


    /**
     * 修改机构资料（重新开户）
     *
     * @param organProfileVo
     * @param userBankVo     4.6.0 版本之后弃用 2018年5月29日14:14:19
     * @return
     */
    @PostMapping("mod_profile")
    @Loggable
    public BaseResult modifyProfile(@Validated OrganProfileVo organProfileVo, @Validated UserBankVo userBankVo) throws BaseAppException {
        BaseResult result = accountValidation.validateOrgProfile(organProfileVo, UserUtil.getLoginUserId(), GlobalConstant.ACTION_MOD);
        if (!result.getSuccess()) {
            return result;
        }
        return userService.updateOrganAccount(UserUtil.getLoginUserId(), organProfileVo, userBankVo);
    }


    /**
     * 修改机构资料（重新开户）
     *
     * @param organProfileVoNew
     * @param userBankVo
     * @return
     * @throws BaseAppException 4.6.0 版本之后使用此接口
     */
    @PostMapping("mod_profile_new")
    @Loggable
    public BaseResult modifyProfileNew(OrganProfileVoNew organProfileVoNew, String organBankId, UserBankVo userBankVo) throws BaseAppException {
        String token = request.getHeader(GlobalConstant.HEADER_AUTH_TOKEN);
        String deviceId = request.getHeader(GlobalConstant.HEADER_APP_DEVICE);
        ValidateTokenResult validateTokenResult = userService.validateToken(token, deviceId);
        Long userId = validateTokenResult.getUserId();
        return organAccountService.reopen(userId, organBankId, organProfileVoNew, userBankVo);
    }


    /**
     * 查询机构资料（基本资料+银行卡）
     *
     * @return
     * @throws BaseAppException 4.6.0 版本之后弃用 2018年5月29日14:14:19
     */
    @GetMapping("qry_profile")
    @Loggable
    public BaseResult qryProfile() throws BaseAppException {
        return userService.qryOrganInfo(UserUtil.getLoginUserId());
    }

    /**
     * 查询机构资料（基本资料+银行卡）
     *
     * @param profileId 机构id
     * @return
     * @throws BaseAppException 4.6.0 版本之后使用此接口
     */
    @GetMapping("qry_profile_new")
    @Loggable
    public BaseResult qryProfileNew(Long profileId) throws BaseAppException {
        return organAccountService.queryOrganInfoByProfileId(profileId);
    }


    /**
     * 用户登录
     *
     * @param loginName
     * @param password
     * @param osType
     * @param deviceId
     * @return
     */
    @PostMapping("login")
    @Loggable
    public BaseResult login(
        @RequestParam Long loginName,
        @RequestParam String password,
        @RequestHeader(value = GlobalConstant.HEADER_OS_TYPE) String osType,
        @RequestHeader(value = GlobalConstant.HEADER_APP_DEVICE) String deviceId) throws BaseAppException {

        return userService.login4Organ(loginName, password, deviceId, osType, RequestUtils.getIpAddr(request));
    }


    /**
     * 机构用户登录
     *
     * @param mobile
     * @param password
     * @param osType
     * @param deviceId
     * @return
     * @throws BaseAppException
     */
    @Loggable
    @PostMapping("login_new")
    public BaseResult loginNewOrgan(String mobile, String password, @RequestHeader(value = GlobalConstant.HEADER_OS_TYPE) String osType
        , @RequestHeader(value = GlobalConstant.HEADER_APP_DEVICE) String deviceId) throws BaseAppException {

        return organAccountService.organLogin(mobile, password, deviceId, osType, RequestUtils.getIpAddr(request));
    }


    /**
     * 重置密码第一步
     *
     * @param mobile
     * @param authCode
     * @return
     */
    @Loggable
    @PostMapping("reset_login_pwd_step1")
    public BaseResult resetLoginPwdStep1(@RequestParam String mobile,
                                         @RequestParam String authCode) {
        boolean verify_code = userService.checkVerifyCode(mobile, authCode, GlobalConstant.SMS_BIZ_CODE_VERIFY);
        if (!verify_code) {
            return new BaseResult(false, "验证码验证失败", GlobalConstant.ERROR_TYPE_BUSINESS);
        }
        User user = userService.getUser(mobile);
        if (user == null) {
            com.codi.base.exception.ExceptionHandler.publish(ErrorConst.ORGAN_IS_NOT_EXIST);
        }

//        if (!user.getIsOrg()) {
//            com.codi.base.exception.ExceptionHandler.publish(ErrorConst.ORGAN_ROLE_PERMISSION_ONLY);
//        }

        if (!EqualsUtil.equals(user.getUserMobile(), mobile)) {
            com.codi.base.exception.ExceptionHandler.publish(ErrorConst.ORGAN_VALID_MOBILE_IS_NOT_SAME);
        }

        return new BaseResult();
    }


    /**
     * 重置密码（找回密码）
     *
     * @param mobile
     * @param authCode
     * @param newPassword
     * @return
     * @throws BaseAppException
     */
    @Loggable
    @PostMapping("reset_login_pwd")
    public BaseResult resetLoginPwd(@RequestParam String mobile,
                                    @RequestParam String authCode,
                                    @RequestParam String newPassword) throws BaseAppException {

        User user = userService.getUser(mobile);
        if (user == null) {
            com.codi.base.exception.ExceptionHandler.publish(ErrorConst.ORGAN_IS_NOT_EXIST);
        }
        if (!EqualsUtil.equals(user.getUserMobile(), mobile)) {
            com.codi.base.exception.ExceptionHandler.publish(ErrorConst.ORGAN_VALID_MOBILE_IS_NOT_SAME);
        }

//        if (!user.getIsOrg()) {
//            com.codi.base.exception.ExceptionHandler.publish(ErrorConst.ORGAN_ROLE_PERMISSION_ONLY);
//        }

        return userService.resetOrgLoginPassword(mobile, authCode, newPassword);
    }

    /**
     * 重置交易密码
     *
     * @param authCode
     * @param newTradePwd
     * @return
     */
    @Loggable
    @PostMapping("/reset_trade_pwd")
    public BaseResult resetTradePwd(@RequestParam String authCode, @RequestParam String newTradePwd,
                                    @RequestHeader(value = GlobalConstant.HEADER_AUTH_TOKEN) String token,
                                    @RequestHeader(value = GlobalConstant.HEADER_APP_DEVICE) String deviceId,
                                    @RequestHeader(value = GlobalConstant.REQUEST_PROFILE_ID) String profileId) {
        ValidateTokenResult validateTokenResult = userService.validateToken(token, deviceId);
        if (!validateTokenResult.getSuccess()) {
            log.error("ValidateTokenInterceptor 验证TOKEN失效");
            // 添加错误信息 - alter by Shangdu - 20170606
            throw new BaseException(validateTokenResult.getErrorCode(), MessageUtil.getErrorMsg(validateTokenResult
                .getErrorCode()), GlobalConstant.ERROR_TYPE_BUSINESS);
        }
        return organAccountService.resetOrgTradePwd(validateTokenResult.getUserId(), Long.valueOf(profileId), authCode, newTradePwd);
    }


    /**
     * 修改手机号
     *
     * @param authCode  旧手机验证码
     * @param newMobile 新手机
     * @param authCode2 新手机验证码
     * @return
     */
    @Loggable
    @PostMapping("change_mobile")
    public BaseResult changeMobile(@RequestParam String authCode,
                                   @RequestParam String newMobile,
                                   @RequestParam String authCode2) throws BaseAppException {
        //TODO 设计的不是太好

        return userService.changeMobile(UserUtil.getLoginUserId(), authCode, newMobile, authCode2);
    }

    /**
     * 查询机构当前审核的状态
     *
     * @return
     */
    @GetMapping("state")
    public BaseResult queryState(Long profileId) {

        AccountOpenResult result = userService.queryOrgState(UserUtil.getLoginUserId(), profileId);

        UserModel userModel = result.getUser();
        if (userModel != null) {
            userModel.setContactIdNo(null);
            userModel.setContactTel(null);
            userModel.setContactName(null);
        }

        return result;
    }

    @Loggable
    @GetMapping("/confirm_pass_notify")
    public BaseResult confirmOrgPassNotifyUser(String profileId) {
        Long pId = Long.valueOf(profileId);
        organProfileService.confirmPassNotifyUser(UserUtil.getLoginUserId(), pId);
        return new BaseResult();
    }

    /**
     * @param t
     * @return
     */
    @GetMapping("/refresh_state")
    public BaseResult refreshAcctState(@RequestParam(defaultValue = "123") String t) {

        if (EqualsUtil.equals(t, "helloworld")) {
            userService.checkOrgAcctStateAndSMS();
        }
        return new BaseResult();
    }

    /**
     * 用户机构所有的banner信息
     *
     * @return
     * @throws BaseAppException
     */
    @Loggable
    @RequestMapping(value = "banners", method = RequestMethod.GET)
    public BaseResult getBannersUser() throws BaseAppException {
        List<SysBanner> list = sysBannerService.queryBannersUser();
        List<SysBanner> listRest = Lists.newArrayList();
        for (SysBanner banner : list) {
            if (banner.getName().endsWith("ORG")) {
                listRest.add(banner);
            }
        }
        if (listRest.size() == 0) {
            listRest.addAll(list);
        }
        BaseResult result = new BaseResult();
        result.setResult(listRest);
        return result;
    }
}
